package com.njtoyo.taxi.admin.logic.data;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.njtoyo.taxi.admin.logic.cache.CacheRecommendCountLogic;
import com.njtoyo.taxi.admin.logic.cache.DriverWorkingLogic;
import com.njtoyo.taxi.admin.logic.cache.LogWorkingTaxiRateLogic;
import com.njtoyo.taxi.admin.mapper.master.entity.Company;
import com.njtoyo.taxi.admin.mapper.master.entity.Driver;
import com.njtoyo.taxi.admin.mapper.master.entity.GeoCanton;
import com.njtoyo.taxi.admin.mapper.master.enums.RankListTimeRangeType;
import com.njtoyo.taxi.admin.mapper.master.mapper.CompanyMapper;
import com.njtoyo.taxi.admin.mapper.master.mapper.GeoCantonMapper;
import com.njtoyo.taxi.admin.mapper.secondary.entity.cache.CacheDriverWorkingCanton;
import com.njtoyo.taxi.admin.mapper.secondary.entity.cache.CacheDriverWorkingCompany;
import com.njtoyo.taxi.admin.mapper.secondary.entity.data.*;
import com.njtoyo.taxi.admin.mapper.secondary.enums.dashboard.DataTrendType;
import com.njtoyo.taxi.admin.mapper.secondary.enums.dashboard.TimeIntervalType;
import com.njtoyo.taxi.admin.rest.presenter.data.data_analysis.RankListCantonPresenter;
import com.njtoyo.taxi.admin.rest.presenter.data.data_analysis.RankListCompanyPresenter;
import com.njtoyo.taxi.admin.rest.presenter.data.data_analysis.RankListDriverPresenter;
import com.njtoyo.taxi.admin.rest.presenter.data.data_analysis.RankListRankTotalPresenter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class RankListLogic {

    @Autowired
    private GeoCantonMapper geoCantonMapper;

    @Autowired
    private CompanyMapper companyMapper;

    @Autowired
    private DashboardOrderLogic dashboardOrderLogic;

    @Autowired
    private DashboardIncomeLogic dashboardIncomeLogic;

    @Autowired
    private CacheRecommendCountLogic cacheRecommendCountLogic;

    @Autowired
    private LogWorkingTaxiRateLogic logWorkingTaxiRateLogic;

    @Autowired
    private DashboardCallLogic dashboardCallLogic;

    @Autowired
    private DriverWorkingLogic driverWorkingLogic;

    // 获取【区域】类型排名（今日、本周、本月）
    public List<RankListCantonPresenter> getListFromMinuteForPlatform(RankListTimeRangeType timeType, List<Long> isImitates, Date startTime, Date endTime, Date comparisonStartTime, Date comparisonEndTime) {
        // 获取区域列表
        List<GeoCanton> cantons = geoCantonMapper.selectList(null);

        List<RankListCantonPresenter> list = new ArrayList<>();

        // 接单量
        List<DashboardOrderMinute> ridePickCount = dashboardOrderLogic.getRidePickCountFromMinuteGroupByCanton(isImitates, startTime, endTime);
        // 接单量-对比
        List<DashboardOrderMinute> contrastRidePickCount = dashboardOrderLogic.getRidePickCountFromMinuteGroupByCanton(isImitates, comparisonStartTime, comparisonEndTime);
        // 接单量-对比-Map
        Map<Long, Long> contrastRidePickCountMap = new HashMap<>();
        for (DashboardOrderMinute item : contrastRidePickCount) {
            contrastRidePickCountMap.put(item.getCantonId(), item.getTotal());
        }

        // 收入金额
        List<DashboardIncomeMinute> onlineAmount = dashboardIncomeLogic.getOnlineAmountFromMinuteGroupByCanton(isImitates, startTime, endTime);
        // 收入金额-对比
        List<DashboardIncomeMinute> contrastOnlineAmount = dashboardIncomeLogic.getOnlineAmountFromMinuteGroupByCanton(isImitates, comparisonStartTime, comparisonEndTime);
        // 收入金额-对比-对比-Map
        Map<Long, BigDecimal> contrastOnlineAmountMap = new HashMap<>();
        for (DashboardIncomeMinute item : contrastOnlineAmount) {
            contrastOnlineAmountMap.put(item.getCantonId(), item.getTotal());
        }

        // 推广量
        List<RankListRankTotalPresenter> recommendCount = cacheRecommendCountLogic.getRecommendCountGroupByCanton(startTime, endTime);
        // 推广量-对比
        List<RankListRankTotalPresenter> contrastRecommendCount = cacheRecommendCountLogic.getRecommendCountGroupByCanton(comparisonStartTime, comparisonEndTime);
        // 推广量-对比-Map
        Map<Long, Long> contrastRecommendCountMap = new HashMap<>();
        for (RankListRankTotalPresenter item : contrastRecommendCount) {
            contrastRecommendCountMap.put(item.getCantonId(), item.getTotalNumber());
        }

        // 出车率
        List<CacheDriverWorkingCanton> workingTaxiRate = driverWorkingLogic.getWorkingTaxiRateGroupByCanton(timeType, startTime, endTime);
        // 出车率-对比
        List<CacheDriverWorkingCanton> contrastWorkingTaxiRate = driverWorkingLogic.getWorkingTaxiRateGroupByCanton(timeType, comparisonStartTime, comparisonEndTime);
        // 出车率-对比-对比-Map
        Map<Long, BigDecimal> contrastWorkingTaxiRateMap = new HashMap<>();
        for (CacheDriverWorkingCanton item : contrastWorkingTaxiRate) {
            contrastWorkingTaxiRateMap.put(item.getCantonId(), item.getRate());
        }

        // 出车数
        List<CacheDriverWorkingCanton> workingTaxiCount = driverWorkingLogic.getWorkingTaxiCountGroupByCanton(timeType, startTime, endTime);

        // 出车数-对比
        List<CacheDriverWorkingCanton> contrastWorkingTaxiCount = driverWorkingLogic.getWorkingTaxiCountGroupByCanton(timeType, comparisonStartTime, comparisonEndTime);
        // 出车数-对比-对比-Map
        Map<Long, Long> contrastWorkingTaxiCountMap = new HashMap<>();
        for (CacheDriverWorkingCanton item : contrastWorkingTaxiCount) {
            contrastWorkingTaxiCountMap.put(item.getCantonId(), item.getWorkingNum());
        }

        // 车辆总数
        List<CacheDriverWorkingCanton> workingTaxiTotalCount = driverWorkingLogic.getWorkingTaxiTotalCountGroupByCanton(timeType, startTime, endTime);

        // 呼叫无应答数
        List<DashboardOrderMinute> noResponseCallCount = dashboardOrderLogic.getNoResponseCallCountFromMinuteGroupByCanton(isImitates, startTime, endTime);
        // 呼叫无应答数-对比
        List<DashboardOrderMinute> contrastNoResponseCallCount = dashboardOrderLogic.getNoResponseCallCountFromMinuteGroupByCanton(isImitates, comparisonStartTime, comparisonEndTime);
        // 呼叫无应答数-对比-Map
        Map<Long, Long> contrastNoResponseCallCountMap = new HashMap<>();
        for (DashboardOrderMinute item : contrastNoResponseCallCount) {
            contrastNoResponseCallCountMap.put(item.getCantonId(), item.getTotal());
        }

        // 呼叫量
        List<DashboardCallMinute> callCount = dashboardCallLogic.getCallCountFromMinuteGroupByCanton(startTime, endTime);
        // 呼叫量-对比
        List<DashboardCallMinute> contrastCallCount = dashboardCallLogic.getCallCountFromMinuteGroupByCanton(comparisonStartTime, comparisonEndTime);
        // 呼叫量-对比-Map
        Map<Long, Long> contrastCallCountMap = new HashMap<>();
        for (DashboardCallMinute item : contrastCallCount) {
            contrastCallCountMap.put(item.getCantonId(), item.getTotal());
        }

        // 循环构建每个区域的数据
        cantons.forEach(canton -> {
            RankListCantonPresenter rank = new RankListCantonPresenter();

            // 接单量
            for (DashboardOrderMinute item : ridePickCount) {
                if (canton.getId().equals(item.getCantonId())) {
                    Long contrastTotal = contrastRidePickCountMap.get(item.getCantonId());
                    // 如果上个周期存在数据
                    if (Objects.nonNull(contrastTotal)) {
                        DataTrendType trend = getTrendForLong(item.getTotal(), contrastTotal);
                        rank.setRidePickCountTrend(trend);
                    } else {
                        rank.setRidePickCountTrend(DataTrendType.growth);
                    }

                    rank.setRidePickCount(item.getTotal());
                    break;
                }
            }

            // 收入金额
            for (DashboardIncomeMinute item : onlineAmount) {
                if (canton.getId().equals(item.getCantonId())) {
                    BigDecimal contrastTotal = contrastOnlineAmountMap.get(item.getCantonId());
                    // 如果上个周期存在数据
                    if (Objects.nonNull(contrastTotal)) {
                        DataTrendType trend = getTrendForBigDecimal(item.getTotal(), contrastTotal);
                        rank.setOnlineAmountTrend(trend);
                    } else {
                        rank.setOnlineAmountTrend(DataTrendType.growth);
                    }

                    rank.setOnlineAmount(item.getTotal());
                    break;
                }
            }

            // 推广量
            for (RankListRankTotalPresenter item : recommendCount) {
                if (canton.getId().equals(item.getCantonId())) {
                    Long contrastTotal = contrastRecommendCountMap.get(item.getCantonId());
                    // 如果上个周期存在数据
                    if (Objects.nonNull(contrastTotal)) {
                        DataTrendType trend = getTrendForLong(item.getTotalNumber(), contrastTotal);
                        rank.setRecommendCountTrend(trend);
                    } else {
                        rank.setRecommendCountTrend(DataTrendType.growth);
                    }

                    rank.setRecommendCount(item.getTotalNumber());
                    break;
                }
            }

            // 出车率
            for (CacheDriverWorkingCanton item : workingTaxiRate) {
                if (canton.getId().equals(item.getCantonId())) {
                    BigDecimal contrastTotal = contrastWorkingTaxiRateMap.get(item.getCantonId());
                    // 如果上个周期存在数据
                    if (Objects.nonNull(contrastTotal)) {
                        DataTrendType trend = getTrendForBigDecimal(item.getRate(), contrastTotal);
                        rank.setWorkingTaxiRateTrend(trend);
                    } else {
                        rank.setWorkingTaxiRateTrend(DataTrendType.growth);
                    }

                    rank.setWorkingTaxiRate(item.getRate());
                    break;
                }
            }

            // 出车数
            for (CacheDriverWorkingCanton item : workingTaxiCount) {
                if (canton.getId().equals(item.getCantonId())) {
                    Long contrastTotal = contrastWorkingTaxiCountMap.get(item.getCantonId());
                    // 如果上个周期存在数据
                    if (Objects.nonNull(contrastTotal)) {
                        DataTrendType trend = getTrendForLong(item.getWorkingNum(), contrastTotal);
                        rank.setWorkingTaxiCountTrend(trend);
                    } else {
                        rank.setWorkingTaxiCountTrend(DataTrendType.growth);
                    }

                    rank.setWorkingTaxiCount(item.getWorkingNum());
                    break;
                }
            }

            // 车辆总数
            for (CacheDriverWorkingCanton item : workingTaxiTotalCount) {
                if (canton.getId().equals(item.getCantonId())) {
                    rank.setWorkingTaxiTotalCount(item.getTotalNum());
                    break;
                }
            }

            // 呼叫无应答数
            for (DashboardOrderMinute item : noResponseCallCount) {
                if (canton.getId().equals(item.getCantonId())) {
                    Long contrastTotal = contrastNoResponseCallCountMap.get(item.getCantonId());
                    // 如果上个周期存在数据
                    if (Objects.nonNull(contrastTotal)) {
                        DataTrendType trend = getTrendForLong(item.getTotal(), contrastTotal);
                        rank.setNoResponseCallCountTrend(trend);
                    } else {
                        rank.setNoResponseCallCountTrend(DataTrendType.growth);
                    }

                    rank.setNoResponseCallCount(item.getTotal());
                    break;
                }
            }

            // 呼叫量
            for (DashboardCallMinute item : callCount) {
                if (canton.getId().equals(item.getCantonId())) {
                    Long contrastTotal = contrastCallCountMap.get(item.getCantonId());
                    // 如果上个周期存在数据
                    if (Objects.nonNull(contrastTotal)) {
                        DataTrendType trend = getTrendForLong(item.getTotal(), contrastTotal);
                        rank.setCallCountTrend(trend);
                    } else {
                        rank.setCallCountTrend(DataTrendType.growth);
                    }

                    rank.setCallCount(item.getTotal());
                    break;
                }
            }

            rank.setId(canton.getId());
            rank.setName(canton.getName());

            list.add(rank);
        });

        return list;
    }

    // 获取区域类型排名(自定义)
    public List<RankListCantonPresenter> getListFromDailyForPlatform(RankListTimeRangeType timeType, List<Long> isImitates, Date startTime, Date endTime, Date comparisonStartTime, Date comparisonEndTime) {
        // 获取区域列表
        List<GeoCanton> cantons = geoCantonMapper.selectList(null);

        List<RankListCantonPresenter> list = new ArrayList<>();

        // 接单量
        List<DashboardOrderDaily> ridePickCount = dashboardOrderLogic.getRidePickCountFromDailyGroupByCanton(isImitates, startTime, endTime);
        // 接单量-对比
        List<DashboardOrderDaily> contrastRidePickCount = dashboardOrderLogic.getRidePickCountFromDailyGroupByCanton(isImitates, comparisonStartTime, comparisonEndTime);
        // 接单量-对比-Map
        Map<Long, Long> contrastRidePickCountMap = new HashMap<>();
        for (DashboardOrderDaily item : contrastRidePickCount) {
            contrastRidePickCountMap.put(item.getCantonId(), item.getTotal());
        }

        // 收入金额
        List<DashboardIncomeDaily> onlineAmount = dashboardIncomeLogic.getOnlineAmountFromDailyGroupByCanton(isImitates, startTime, endTime);
        // 收入金额-对比
        List<DashboardIncomeDaily> contrastOnlineAmount = dashboardIncomeLogic.getOnlineAmountFromDailyGroupByCanton(isImitates, comparisonStartTime, comparisonEndTime);
        // 收入金额-对比-对比-Map
        Map<Long, BigDecimal> contrastOnlineAmountMap = new HashMap<>();
        for (DashboardIncomeDaily item : contrastOnlineAmount) {
            contrastOnlineAmountMap.put(item.getCantonId(), item.getTotal());
        }

        // 推广量
        List<RankListRankTotalPresenter> recommendCount = cacheRecommendCountLogic.getRecommendCountGroupByCanton(startTime, endTime);
        // 推广量-对比
        List<RankListRankTotalPresenter> contrastRecommendCount = cacheRecommendCountLogic.getRecommendCountGroupByCanton(comparisonStartTime, comparisonEndTime);
        // 推广量-对比-Map
        Map<Long, Long> contrastRecommendCountMap = new HashMap<>();
        for (RankListRankTotalPresenter item : contrastRecommendCount) {
            contrastRecommendCountMap.put(item.getCantonId(), item.getTotalNumber());
        }

        // 出车率
        List<CacheDriverWorkingCanton> workingTaxiRate = driverWorkingLogic.getWorkingTaxiRateGroupByCanton(timeType, startTime, endTime);
        // 出车率-对比
        List<CacheDriverWorkingCanton> contrastWorkingTaxiRate = driverWorkingLogic.getWorkingTaxiRateGroupByCanton(timeType, comparisonStartTime, comparisonEndTime);
        // 出车率-对比-对比-Map
        Map<Long, BigDecimal> contrastWorkingTaxiRateMap = new HashMap<>();
        for (CacheDriverWorkingCanton item : contrastWorkingTaxiRate) {
            contrastWorkingTaxiRateMap.put(item.getCantonId(), item.getRate());
        }

        // 出车数
        List<CacheDriverWorkingCanton> workingTaxiCount = driverWorkingLogic.getWorkingTaxiCountGroupByCanton(timeType, startTime, endTime);
        // 出车数-对比
        List<CacheDriverWorkingCanton> contrastWorkingTaxiCount = driverWorkingLogic.getWorkingTaxiCountGroupByCanton(timeType, comparisonStartTime, comparisonEndTime);
        // 出车数-对比-对比-Map
        Map<Long, Long> contrastWorkingTaxiCountMap = new HashMap<>();
        for (CacheDriverWorkingCanton item : contrastWorkingTaxiCount) {
            contrastWorkingTaxiCountMap.put(item.getCantonId(), item.getWorkingNum());
        }

        // 车辆总数
        List<CacheDriverWorkingCanton> workingTaxiTotalCount = driverWorkingLogic.getWorkingTaxiTotalCountGroupByCanton(timeType, startTime, endTime);

        // 呼叫无应答数
        List<DashboardOrderDaily> noResponseCallCount = dashboardOrderLogic.getNoResponseCallCountFromDailyGroupByCanton(isImitates, startTime, endTime);
        // 呼叫无应答数-对比
        List<DashboardOrderDaily> contrastNoResponseCallCount = dashboardOrderLogic.getNoResponseCallCountFromDailyGroupByCanton(isImitates, comparisonStartTime, comparisonEndTime);
        // 呼叫无应答数-对比-Map
        Map<Long, Long> contrastNoResponseCallCountMap = new HashMap<>();
        for (DashboardOrderDaily item : contrastNoResponseCallCount) {
            contrastNoResponseCallCountMap.put(item.getCantonId(), item.getTotal());
        }

        // 呼叫量
        List<DashboardCallDaily> callCount = dashboardCallLogic.getCallCountFromDailyGroupByCanton(startTime, endTime);
        // 呼叫量-对比
        List<DashboardCallDaily> contrastCallCount = dashboardCallLogic.getCallCountFromDailyGroupByCanton(comparisonStartTime, comparisonEndTime);
        // 呼叫量-对比-Map
        Map<Long, Long> contrastCallCountMap = new HashMap<>();
        for (DashboardCallDaily item : contrastCallCount) {
            contrastCallCountMap.put(item.getCantonId(), item.getTotal());
        }

        // 循环构建每个区域的数据
        cantons.forEach(canton -> {
            RankListCantonPresenter rank = new RankListCantonPresenter();

            // 接单量
            for (DashboardOrderDaily item : ridePickCount) {
                if (canton.getId().equals(item.getCantonId())) {
                    Long contrastTotal = contrastRidePickCountMap.get(item.getCantonId());
                    // 如果上个周期存在数据
                    if (Objects.nonNull(contrastTotal)) {
                        DataTrendType trend = getTrendForLong(item.getTotal(), contrastTotal);
                        rank.setRidePickCountTrend(trend);
                    } else {
                        rank.setRidePickCountTrend(DataTrendType.growth);
                    }

                    rank.setRidePickCount(item.getTotal());
                    break;
                }
            }

            // 收入金额
            for (DashboardIncomeDaily item : onlineAmount) {
                if (canton.getId().equals(item.getCantonId())) {
                    BigDecimal contrastTotal = contrastOnlineAmountMap.get(item.getCantonId());
                    // 如果上个周期存在数据
                    if (Objects.nonNull(contrastTotal)) {
                        DataTrendType trend = getTrendForBigDecimal(item.getTotal(), contrastTotal);
                        rank.setOnlineAmountTrend(trend);
                    } else {
                        rank.setOnlineAmountTrend(DataTrendType.growth);
                    }

                    rank.setOnlineAmount(item.getTotal());
                    break;
                }
            }

            // 推广量
            for (RankListRankTotalPresenter item : recommendCount) {
                if (canton.getId().equals(item.getCantonId())) {
                    Long contrastTotal = contrastRecommendCountMap.get(item.getCantonId());
                    // 如果上个周期存在数据
                    if (Objects.nonNull(contrastTotal)) {
                        DataTrendType trend = getTrendForLong(item.getTotalNumber(), contrastTotal);
                        rank.setRecommendCountTrend(trend);
                    } else {
                        rank.setRecommendCountTrend(DataTrendType.growth);
                    }

                    rank.setRecommendCount(item.getTotalNumber());
                    break;
                }
            }

            // 出车率
            for (CacheDriverWorkingCanton item : workingTaxiRate) {
                if (canton.getId().equals(item.getCantonId())) {
                    BigDecimal contrastTotal = contrastWorkingTaxiRateMap.get(item.getCantonId());
                    // 如果上个周期存在数据
                    if (Objects.nonNull(contrastTotal)) {
                        DataTrendType trend = getTrendForBigDecimal(item.getRate(), contrastTotal);
                        rank.setWorkingTaxiRateTrend(trend);
                    } else {
                        rank.setWorkingTaxiRateTrend(DataTrendType.growth);
                    }

                    rank.setWorkingTaxiRate(item.getRate());
                    break;
                }
            }

            // 出车数
            for (CacheDriverWorkingCanton item : workingTaxiCount) {
                if (canton.getId().equals(item.getCantonId())) {
                    Long contrastTotal = contrastWorkingTaxiCountMap.get(item.getCantonId());
                    // 如果上个周期存在数据
                    if (Objects.nonNull(contrastTotal)) {
                        DataTrendType trend = getTrendForLong(item.getWorkingNum(), contrastTotal);
                        rank.setWorkingTaxiCountTrend(trend);
                    } else {
                        rank.setWorkingTaxiCountTrend(DataTrendType.growth);
                    }

                    rank.setWorkingTaxiCount(item.getWorkingNum());
                    break;
                }
            }

            // 车辆总数
            for (CacheDriverWorkingCanton item : workingTaxiTotalCount) {
                if (canton.getId().equals(item.getCantonId())) {
                    rank.setWorkingTaxiTotalCount(item.getTotalNum());
                    break;
                }
            }

            // 呼叫无应答数
            for (DashboardOrderDaily item : noResponseCallCount) {
                if (canton.getId().equals(item.getCantonId())) {
                    Long contrastTotal = contrastNoResponseCallCountMap.get(item.getCantonId());
                    // 如果上个周期存在数据
                    if (Objects.nonNull(contrastTotal)) {
                        DataTrendType trend = getTrendForLong(item.getTotal(), contrastTotal);
                        rank.setNoResponseCallCountTrend(trend);
                    } else {
                        rank.setNoResponseCallCountTrend(DataTrendType.growth);
                    }

                    rank.setNoResponseCallCount(item.getTotal());
                    break;
                }
            }

            // 呼叫量
            for (DashboardCallDaily item : callCount) {
                if (canton.getId().equals(item.getCantonId())) {
                    Long contrastTotal = contrastCallCountMap.get(item.getCantonId());
                    // 如果上个周期存在数据
                    if (Objects.nonNull(contrastTotal)) {
                        DataTrendType trend = getTrendForLong(item.getTotal(), contrastTotal);
                        rank.setCallCountTrend(trend);
                    } else {
                        rank.setCallCountTrend(DataTrendType.growth);
                    }

                    rank.setCallCount(item.getTotal());
                    break;
                }
            }

            rank.setId(canton.getId());
            rank.setName(canton.getName());

            list.add(rank);
        });

        return list;
    }

    // 获取【公司】类型排名(自定义)
    public List<RankListCompanyPresenter> getListFromDailyForCanton(RankListTimeRangeType timeType, List<Long> isImitates, Date startTime, Date endTime, List<Long> companyIds) {
        // 获取公司列表
        QueryWrapper<Company> companyWrapper = new QueryWrapper<>();
        companyWrapper.in("id", companyIds);
        List<Company> companyList = companyMapper.selectList(companyWrapper);

        List<RankListCompanyPresenter> list = new ArrayList<>();

        // 接单量
        List<DashboardOrderDaily> ridePickCount = dashboardOrderLogic.getRidePickCountFromDailyGroupByCompany(isImitates, startTime, endTime, companyIds);

        // 收入金额
        List<DashboardIncomeDaily> onlineAmount = dashboardIncomeLogic.getOnlineAmountFromDailyGroupByCompany(isImitates, startTime, endTime, companyIds);

        // 推广量
        List<RankListRankTotalPresenter> recommendCount = cacheRecommendCountLogic.getRecommendCountGroupByCompany(startTime, endTime, companyIds);

        // 出车率
        List<CacheDriverWorkingCompany> workingTaxiRate = driverWorkingLogic.getWorkingTaxiRateGroupByCompany(timeType, startTime, endTime, companyIds);

        // 出车数
        List<CacheDriverWorkingCompany> workingTaxiCount = driverWorkingLogic.getWorkingTaxiCountGroupByCompany(timeType, startTime, endTime, companyIds);

        // 车辆总数
        List<CacheDriverWorkingCompany> workingTaxiTotalCount = driverWorkingLogic.getWorkingTaxiTotalCountGroupByCompany(timeType, startTime, endTime, companyIds);

        // 循环构建每个公司的数据
        companyList.forEach(company -> {
            RankListCompanyPresenter rank = new RankListCompanyPresenter();

            // 接单量
            for (DashboardOrderDaily item : ridePickCount) {
                if (company.getId().equals(item.getCompanyId())) {
                    rank.setRidePickCount(item.getTotal());
                    break;
                }
            }

            // 收入金额
            for (DashboardIncomeDaily item : onlineAmount) {
                if (company.getId().equals(item.getCompanyId())) {
                    rank.setOnlineAmount(item.getTotal());
                    break;
                }
            }

            // 推广量
            for (RankListRankTotalPresenter item : recommendCount) {
                if (company.getId().equals(item.getCompanyId())) {
                    rank.setRecommendCount(item.getTotalNumber());
                    break;
                }
            }

            // 出车率
            for (CacheDriverWorkingCompany item : workingTaxiRate) {
                if (company.getId().equals(item.getCompanyId())) {
                    rank.setWorkingTaxiRate(item.getRate());
                    break;
                }
            }

            // 出车数
            for (CacheDriverWorkingCompany item : workingTaxiCount) {
                if (company.getId().equals(item.getCompanyId())) {
                    rank.setWorkingTaxiCount(item.getWorkingNum());
                    break;
                }
            }

            // 车辆总数
            for (CacheDriverWorkingCompany item : workingTaxiTotalCount) {
                if (company.getId().equals(item.getCompanyId())) {
                    rank.setWorkingTaxiTotalCount(item.getTotalNum());
                    break;
                }
            }

            rank.setId(company.getId());
            rank.setName(company.getName());

            list.add(rank);
        });

        return list;
    }

    // 获取【公司】类型排名(今日、本周、本月)
    public List<RankListCompanyPresenter> getListFromMinuteForCanton(RankListTimeRangeType timeType, List<Long> isImitates, Date startTime, Date endTime, List<Long> companyIds) {
        // 获取公司列表
        QueryWrapper<Company> companyWrapper = new QueryWrapper<>();
        companyWrapper.in("id", companyIds);
        List<Company> companyList = companyMapper.selectList(companyWrapper);

        List<RankListCompanyPresenter> list = new ArrayList<>();

        // 接单量
        List<DashboardOrderMinute> ridePickCount = dashboardOrderLogic.getRidePickCountFromMinuteGroupByCompany(isImitates, startTime, endTime, companyIds);

        // 收入金额
        List<DashboardIncomeMinute> onlineAmount = dashboardIncomeLogic.getOnlineAmountFromMinuteGroupByCompany(isImitates, startTime, endTime, companyIds);

        // 推广量
        List<RankListRankTotalPresenter> recommendCount = cacheRecommendCountLogic.getRecommendCountGroupByCompany(startTime, endTime, companyIds);

        // 出车率
        List<CacheDriverWorkingCompany> workingTaxiRate = driverWorkingLogic.getWorkingTaxiRateGroupByCompany(timeType, startTime, endTime, companyIds);

        // 出车数
        List<CacheDriverWorkingCompany> workingTaxiCount = driverWorkingLogic.getWorkingTaxiCountGroupByCompany(timeType, startTime, endTime, companyIds);

        // 车辆总数
        List<CacheDriverWorkingCompany> workingTaxiTotalCount = driverWorkingLogic.getWorkingTaxiTotalCountGroupByCompany(timeType, startTime, endTime, companyIds);

        // 循环构建每个公司的数据
        companyList.forEach(company -> {
            RankListCompanyPresenter rank = new RankListCompanyPresenter();

            // 接单量
            for (DashboardOrderMinute item : ridePickCount) {
                if (company.getId().equals(item.getCompanyId())) {
                    rank.setRidePickCount(item.getTotal());
                    break;
                }
            }

            // 收入金额
            for (DashboardIncomeMinute item : onlineAmount) {
                if (company.getId().equals(item.getCompanyId())) {
                    rank.setOnlineAmount(item.getTotal());
                    break;
                }
            }

            // 推广量
            for (RankListRankTotalPresenter item : recommendCount) {
                if (company.getId().equals(item.getCompanyId())) {
                    rank.setRecommendCount(item.getTotalNumber());
                    break;
                }
            }

            // 出车率
            for (CacheDriverWorkingCompany item : workingTaxiRate) {
                if (company.getId().equals(item.getCompanyId())) {
                    rank.setWorkingTaxiRate(item.getRate());
                    break;
                }
            }

            // 出车数
            for (CacheDriverWorkingCompany item : workingTaxiCount) {
                if (company.getId().equals(item.getCompanyId())) {
                    rank.setWorkingTaxiCount(item.getWorkingNum());
                    break;
                }
            }

            // 车辆总数
            for (CacheDriverWorkingCompany item : workingTaxiTotalCount) {
                if (company.getId().equals(item.getCompanyId())) {
                    rank.setWorkingTaxiTotalCount(item.getTotalNum());
                    break;
                }
            }

            rank.setId(company.getId());
            rank.setName(company.getName());

            list.add(rank);
        });

        return list;
    }

    // 获取【司机】类型排名(自定义)
    public List<RankListDriverPresenter> getListForCompany(TimeIntervalType type, Date startTime, Date endTime, List<Driver> driverList) {
        List<RankListDriverPresenter> list = new ArrayList<>();

        List<Long> driverIds = driverList.stream().map(Driver::getId).collect(Collectors.toList());

        // 接单量
        List<RankListRankTotalPresenter> ridePickCount = dashboardOrderLogic.getRidePickCountGroupByDriver(startTime, endTime, driverIds);

        // 收入金额
        List<RankListRankTotalPresenter> onlineAmount = dashboardIncomeLogic.getOnlineAmountGroupByDriver(startTime, endTime, driverIds);

        // 推广量
        List<RankListRankTotalPresenter> recommendCount = cacheRecommendCountLogic.getRecommendCountGroupByDriver(startTime, endTime, driverIds);

        // 循环构建每个司机的数据
        driverList.forEach(driver -> {
            RankListDriverPresenter rank = new RankListDriverPresenter();

            // 接单量
            for (RankListRankTotalPresenter item : ridePickCount) {
                if (driver.getId().equals(item.getDriverId())) {
                    rank.setRidePickCount(item.getTotalNumber());
                    break;
                }
            }

            // 收入金额
            for (RankListRankTotalPresenter item : onlineAmount) {
                if (driver.getId().equals(item.getDriverId())) {
                    rank.setOnlineAmount(item.getTotalValue());
                    break;
                }
            }

            // 推广量
            for (RankListRankTotalPresenter item : recommendCount) {
                if (driver.getId().equals(item.getDriverId())) {
                    rank.setRecommendCount(item.getTotalNumber());
                    break;
                }
            }

            // 评分
            rank.setDriverScore(driver.getMarkScore());

            rank.setId(driver.getId());
            rank.setName(driver.getName());

            list.add(rank);
        });

        return list;
    }

    private DataTrendType getTrendForLong(Long num, Long contrastNum) {
        if (num > contrastNum) {
            return DataTrendType.growth;
        } else if (num < contrastNum) {
            return DataTrendType.decline;
        }

        return DataTrendType.unchanged;
    }

    private DataTrendType getTrendForBigDecimal(BigDecimal num, BigDecimal contrastNum) {
        BigDecimal res = num.subtract(contrastNum);

        if (res.signum() == 1) {
            return DataTrendType.growth;
        } else if (res.signum() == -1) {
            return DataTrendType.decline;
        }

        return DataTrendType.unchanged;
    }
}
